from sqlalchemy.orm import backref

from app import db, jwt
from datetime import datetime

from app.models.Role import Role
from app.models.Shop import Shop
from app.models.Resource import Resource

# 用户-组织关联表
# 定义用户和组织机构的多对多关系
user_organization_table = db.Table('syuser_SYORGANIZATION', db.metadata,
                                   db.Column('SYUSER_ID', db.String, db.ForeignKey('sys_user.ID')),
                                   db.Column('SYORGANIZATION_ID', db.String, db.ForeignKey('sys_organization.ID')))

# 用户-角色关联表
# 定义用户和角色的多对多关系
user_role_table = db.Table('syuser_SYROLE', db.metadata,
                          db.Column('SYUSER_ID', db.String, db.ForeignKey('sys_user.ID')),
                          db.Column('SYROLE_ID', db.String, db.ForeignKey('sys_role.ID')))

# JWT身份加载器
# 用于从用户对象中提取身份标识符
@jwt.user_identity_loader
def user_identity_lookup(user):
    return user.ID

# JWT用户加载器
# 用于根据JWT令牌中的身份信息加载用户对象
@jwt.user_lookup_loader
def user_lookup_callback(_jwt_header, jwt_data):
    identity = jwt_data["sub"]
    return User.query.filter_by(ID=identity).one_or_none()

    
class User(db.Model):
    """用户模型类
    
    用于存储和管理系统用户信息，包括基本信息、认证信息、组织关系等
    支持与组织机构、角色和商店的关联关系
    """
    __tablename__ = 'sys_user'
    # 基本信息字段
    ID = db.Column(db.String(36), primary_key=True)  # 用户唯一标识
    CREATEDATETIME = db.Column(db.DateTime, index=True, default=datetime.now)  # 创建时间
    UPDATEDATETIME = db.Column(db.DateTime, index=True, default=datetime.now)  # 更新时间
    LOGINNAME = db.Column(db.String(100), unique=True, index=True)  # 登录名
    PWD = db.Column(db.String(256))  # 密码
    NAME = db.Column(db.String(100))  # 用户姓名
    SEX = db.Column(db.String(1))  # 性别
    AGE = db.Column(db.Integer)  # 年龄
    PHOTO = db.Column(db.String(200))  # 头像URL
    EMPLOYDATE = db.Column(db.DATETIME, default=datetime.now)  # 入职日期
    EMAIL = db.Column(db.String(50))  # 电子邮箱
    PHONENUMBER = db.Column(db.String(11))  # 手机号码
    STATUS = db.Column(db.String(10))  # 用户状态
    SALT = db.Column(db.String(64))  # 密码加密盐值

    OPENID = db.Column(db.String(50))  # 微信openid

    # created_time
    #

    # 关联关系定义
    # 用户-组织多对多关系
    organizations = db.relationship('Organization',
                                    secondary=user_organization_table,
                                    backref=db.backref('users', lazy='dynamic'),)

    # 用户-角色多对多关系
    roles = db.relationship('Role',
                            secondary=user_role_table,
                            backref=db.backref('users', lazy='dynamic'),
                            lazy="dynamic")
    
    # 用户-商店一对一关系
    shop = db.relationship('Shop', backref='user', uselist=False)

    def get_id(self):
        """获取用户ID
        
        Returns:
            str: 用户ID的字符串形式
        """
        return str(self.ID)

    def have_permission(self, url):
        """检查用户是否具有访问指定URL的权限
        
        通过检查用户的角色和组织机构关联的资源权限来判断
        首先检查用户角色的权限，如果没有则检查用户所属组织的权限
        
        Args:
            url (str): 需要检查权限的URL
            
        Returns:
            bool: 如果用户具有权限返回True，否则返回False
        """
        # 检查角色权限
        permissions = []
        for role in self.roles:
            permissions.extend([resource for resource in role.resources])

        if filter(lambda x: x.URL == url, permissions):
            return True

        # 检查组织权限
        permissions = []
        for organization in self.organizations:
            permissions.extend([resource for resource in organization.resources])

        return filter(lambda x: x.NAME == url, permissions)
        
    def __repr__(self):
        """返回用户对象的字符串表示
        
        Returns:
            str: 用户对象的字符串表示，包含用户名
        """
        return '<User %r>\n' %(self.NAME)

    def to_json(self):
        """将用户对象转换为JSON格式
        
        转换用户的基本信息、组织信息、角色信息和商店信息为JSON格式
        
        Returns:
            dict: 包含用户所有相关信息的字典
        """
        # 基本信息
        json = {
            'userId': self.ID,
            'createTime': self.CREATEDATETIME.strftime('%Y-%m-%d %H:%M:%S'),
            'updateTime': self.UPDATEDATETIME.strftime('%Y-%m-%d %H:%M:%S'),
            'userName': self.LOGINNAME,
            'nickName': self.NAME,
            'sex': self.SEX,
            'age': self.AGE,
            "status": self.STATUS,
            'photo': self.PHOTO,
            'email': self.EMAIL,
            'phonenumber': self.PHONENUMBER,
            'openid': self.OPENID,
            #'employdate': self.EMPLOYDATE.strftime('%Y-%m-%d %H:%M:%S'),

        }

        # 添加组织信息
        if len(self.organizations) > 0:
            json['dept']  = self.organizations[0].to_json()
            json['deptId'] = self.organizations[0].ID

        # 添加角色信息
        if len(self.roles.all()) > 0:
            json['roles'] = [role.to_json() for role in self.roles.all()]

        # 添加商店信息
        if self.shop:
            json['shop_name'] = self.shop.shop_name

        return json


